home *** CD-ROM | disk | FTP | other *** search
/ Programming Sound Cards / Programming Sound Cards.iso / sound_87 / vtcfg.pas < prev    next >
Pascal/Delphi Source File  |  1995-01-01  |  14KB  |  467 lines

  1. {****************************************************************************}
  2. {                                                                            }
  3. { MODULE:         VTCfg                                                      }
  4. {                                                                            }
  5. { DESCRIPTION:    Implements the reading of the VT.CFG configuration file.   }
  6. {                                                                            }
  7. { AUTHOR:         Juan Carlos Arévalo                                        }
  8. {                                                                            }
  9. { MODIFICATIONS:  Nobody (yet ;-)                                            }
  10. {                                                                            }
  11. { HISTORY:        17-Oct-1992 Documentation                                  }
  12. {                                                                            }
  13. { (C) 1992 VangeliSTeam                                                      }
  14. {____________________________________________________________________________}
  15.  
  16. UNIT VTCfg;
  17.  
  18. {$I-}
  19.  
  20. INTERFACE
  21.  
  22. USES Dos,
  23.      VTGlobal,
  24.      PlayMod, ModCommands, SongElements,
  25.      SoundDevices, DevSpkr, DevSB, DevDAC,
  26.      Vid43, SoundBlaster, SwapStream;
  27.  
  28.  
  29.  
  30.  
  31. PROCEDURE ReadConfiguration(FName: PathStr); { Read and interpretate the file as a configuration file. }
  32.  
  33.  
  34.  
  35.  
  36. IMPLEMENTATION
  37.  
  38.  
  39. VAR
  40.   ConfFile : TEXT;   { Open configuration file.      }
  41.   Line     : STRING; { Last line read from the file. }
  42.  
  43.  
  44.  
  45.  
  46. {----------------------------------------------------------------------------}
  47. { Miscelaneous string handling routines.                                     }
  48. {____________________________________________________________________________}
  49.  
  50.  
  51. { KillSpaces. Deletes the blanks from the beginning and end of the string. }
  52.  
  53. PROCEDURE KillSpaces(VAR s: STRING);
  54.   CONST
  55.     ValidBlanks = [' ', #9, #0, #255];
  56.   BEGIN
  57.     WHILE (Length(s) > 0) AND (s[1]         IN ValidBlanks) DO
  58.       s := COPY(s, 2, 255);
  59.     WHILE (Length(s) > 0) AND (s[Length(s)] IN ValidBlanks) DO
  60.       DEC(s[0]);
  61.   END;
  62.  
  63.  
  64. { NotInStr. Returns TRUE if the first parameter doesn't contain the second
  65.             at the beginning.                                              }
  66.  
  67. FUNCTION NotInStr(s, ss: STRING) : BOOLEAN;
  68.   VAR
  69.     i : WORD;
  70.   BEGIN
  71.     NotInStr := TRUE;
  72.     IF Length(ss) > Length(s) THEN EXIT;
  73.     FOR i := 1 TO Length(ss) DO
  74.       IF UpCase(s[i]) <> UpCase(ss[i]) THEN EXIT;
  75.     NotInStr := FALSE;
  76.   END;
  77.  
  78.  
  79.  
  80.  
  81. {----------------------------------------------------------------------------}
  82. { Routines for reading different data types They all assume that 'Line'      }
  83. { contains a string in the format "<Identifier> = <value>".                  }
  84. { Their names ar self-explicative.                                           }
  85. {____________________________________________________________________________}
  86.  
  87.  
  88. FUNCTION GetString(VAR st: STRING; ml: WORD) : BOOLEAN;
  89.   VAR
  90.     s     : STRING;
  91.     s1    : STRING;
  92.     i, j,
  93.     k, l  : LONGINT;
  94.   BEGIN
  95.     i := Pos('=', Line) + 1;
  96.  
  97.     s := Copy(Line, i, 255);
  98.     KillSpaces(s);
  99.  
  100.     s1 := '';
  101.     WHILE Length(s) > 0 DO
  102.         IF s[1] = '''' THEN
  103.           BEGIN
  104.             s  := Copy(s, 2, 255);
  105.             i  := Pos('''', s);
  106.             IF i = 0 THEN i := 254;
  107.             s1 := s1 + Copy(s, 1, i-1);
  108.             IF (Length(s) > i) AND (s[i+1] = '''') THEN
  109.               s1 := s1 + '''';
  110.             s := Copy(s, i+1, 255);
  111.             IF Pos('''', s) = 0 THEN s := '';
  112.           END
  113.         ELSE
  114.           BEGIN
  115.             j := Pos(';', s);
  116.             k := Pos(':', s); IF (k <> 0) AND (j > k) THEN j := k;
  117.             k := Pos('#', s); IF (k <> 0) AND (j > k) THEN j := k;
  118.                                  IF  j =  0           THEN j := Length(s) + 1;
  119.             s1 := Copy(s, 1, j-1);
  120.             KillSpaces(s1);
  121.             s := ''
  122.           END;
  123.  
  124.     IF Length(s1) > ml THEN s1[0] := CHAR(ml);
  125.     st := s1;
  126.     GetString := TRUE;
  127.   END;
  128.  
  129.  
  130. FUNCTION GetBool(VAR b: BOOLEAN) : BOOLEAN;
  131.   VAR
  132.     s       : STRING;
  133.   BEGIN
  134.     GetBool := FALSE;
  135.     IF NOT GetString(s, SIZEOF(s) - 1) THEN EXIT;
  136.     IF (NOT NotInStr(s, 'S'    )) OR
  137.        (NOT NotInStr(s, 'Y'    )) OR
  138.        (NOT NotInStr(s, 'OUI'  )) OR
  139.        (NOT NotInStr(s, 'DA'   )) OR
  140.        (NOT NotInStr(s, 'POR'  )) OR
  141.        (NOT NotInStr(s, 'TAMB' )) OR
  142.        (NOT NotInStr(s, 'ALSO' )) OR
  143.        (NOT NotInStr(s, 'TRUE' )) OR
  144.        (NOT NotInStr(s, 'VERD' )) OR
  145.        (NOT NotInStr(s, 'CIER' )) OR
  146.        (NOT NotInStr(s, '1'    )) THEN
  147.       BEGIN
  148.         b       := TRUE;
  149.         GetBool := TRUE;
  150.       END
  151.     ELSE IF (NOT NotInStr(s, 'N'     )) OR
  152.             (NOT NotInStr(s, 'PAS'   )) OR
  153.             (NOT NotInStr(s, 'TAMP'  )) OR
  154.             (NOT NotInStr(s, 'FALS'  )) OR
  155.             (NOT NotInStr(s, '0'     )) THEN
  156.       BEGIN
  157.         b       := FALSE;
  158.         GetBool := TRUE;
  159.       END;
  160.   END;
  161.  
  162.  
  163. FUNCTION GetPath(VAR p: PathStr) : BOOLEAN;
  164.   BEGIN
  165.     GetPath := FALSE;
  166.     IF NOT GetString(p, SIZEOF(p) - 1) THEN EXIT;
  167.     p := FExpand(p);
  168.     GetPath := TRUE;
  169.   END;
  170.  
  171.  
  172. FUNCTION GetNum(VAR b: LONGINT) : BOOLEAN;
  173.   TYPE
  174.     LP = ^LONGINT;
  175.   VAR
  176.     s       : STRING;
  177.     i, j, k : LONGINT;
  178.   BEGIN
  179.     i := Pos('=', Line) + 1;
  180.     j := Pos(';', Line);
  181.     k := Pos(':', Line); IF (k <> 0) AND (j > k) THEN j := k;
  182.     k := Pos('#', Line); IF (k <> 0) AND (j > k) THEN j := k;
  183.                          IF               j = 0  THEN j := Length(Line) + 1;
  184.     s := Copy(Line, i, j-i);
  185.     KillSpaces(s);
  186.  
  187.     j := 1;
  188.  
  189.     IF (Length(s) > 3) AND (s[1] = '[') THEN
  190.       BEGIN
  191.         j := Pos(']', s);
  192.         IF j <> 0 THEN
  193.           BEGIN
  194.             VAL(Copy(s, 2, j-2), i, WORD(j));
  195.             IF j = 0 THEN
  196.               i := LP(Ptr((i AND $F0000) SHR 4, i AND $FFFF))^;
  197.           END
  198.         ELSE
  199.           j := 1;
  200.       END
  201.     ELSE
  202.       VAL(s, i, WORD(j));
  203.  
  204.     IF j <> 0 THEN
  205.       BEGIN
  206.         GetNum := FALSE;
  207.         EXIT;
  208.       END;
  209.     b := i;
  210.     GetNum := TRUE;
  211.   END;
  212.  
  213.  
  214. FUNCTION GetWord(VAR b: WORD) : BOOLEAN;
  215.   VAR
  216.     l : LONGINT;
  217.   BEGIN
  218.     IF GetNum(l) THEN
  219.       BEGIN
  220.         b := WORD(l);
  221.         GetWord := TRUE;
  222.       END
  223.     ELSE
  224.       GetWord := FALSE;
  225.   END;
  226.  
  227.  
  228. FUNCTION GetByte(VAR b: BYTE) : BOOLEAN;
  229.   VAR
  230.     l : LONGINT;
  231.   BEGIN
  232.     IF GetNum(l) THEN
  233.       BEGIN
  234.         b := BYTE(l);
  235.         GetByte := TRUE;
  236.       END
  237.     ELSE
  238.       GetByte := FALSE;
  239.   END;
  240.  
  241.  
  242.  
  243.  
  244. {----------------------------------------------------------------------------}
  245. { Routines that implement the actual interpretation of the identifiers.      }
  246. { One routine for each section.                                              }
  247. {____________________________________________________________________________}
  248.  
  249. TYPE
  250.   Proc = PROCEDURE;
  251.  
  252.  
  253. { DoSectSB. [VT-SBlaster] (Sound Blaster) section. }
  254.  
  255. PROCEDURE DoSectSB; FAR;
  256.   BEGIN
  257.     IF NOT NotInStr(Line, 'IRQ'         ) THEN GetWord(SbIrq);
  258.     IF NOT NotInStr(Line, 'Port'        ) THEN GetWord(SbPort);
  259.     IF NOT NotInStr(Line, 'DMA'         ) THEN GetWord(SbDMAChan);
  260.     IF NOT NotInStr(Line, 'SbSplTimeout') THEN GetWord(SbSplTimeout);
  261.     IF NOT NotInStr(Line, 'HiSpeedDMA'  ) THEN GetBool(SbHiSpeed);
  262.   END;
  263.  
  264.  
  265. { DoSectSBPro. [VT-SBPro] (Sound Blaster Pro) section. }
  266.  
  267. PROCEDURE DoSectSBPro; FAR;
  268.   BEGIN
  269.     IF NOT NotInStr(Line, 'MasterVol'   ) THEN GetByte(SbProMixMasterVol);
  270.     IF NOT NotInStr(Line, 'DACVol'      ) THEN GetByte(SbProMixDACVol);
  271.     IF NOT NotInStr(Line, 'FMVol'       ) THEN GetByte(SbProMixFMVol);
  272.     IF NOT NotInStr(Line, 'Filter'      ) THEN GetBool(SbProMixFilter);
  273.   END;
  274.  
  275.  
  276. { DoSectDAC. [VT-DAC] section. }
  277.  
  278. PROCEDURE DoSectDAC; FAR;
  279.   BEGIN
  280.     IF NOT NotInStr(Line, 'Port' ) THEN GetWord(DACPort);
  281.     IF NOT NotInStr(Line, 'LPort') THEN GetWord(LDACPort);
  282.     IF NOT NotInStr(Line, 'RPort') THEN GetWord(RDACPort);
  283.   END;
  284.  
  285.  
  286. { DoSectPlayMod. [VT-PlayMod] section }
  287.  
  288. PROCEDURE DoSectPlayMod; FAR;
  289.   BEGIN
  290.     IF NOT NotInStr(Line, 'PermitFade'  ) THEN GetBool(PermitFade);
  291.     IF NOT NotInStr(Line, 'FadeSpeed'   ) THEN GetWord(FadeIncr);
  292.     IF NOT NotInStr(Line, 'LoopMod'     ) THEN GetBool(VTLoopMod);
  293.     IF NOT NotInStr(Line, 'ForceLoopMod') THEN GetBool(ForceLoopMod);
  294.     IF NOT NotInStr(Line, 'ShellLoopMod') THEN GetBool(ShellLoopMod);
  295.     IF NOT NotInStr(Line, 'SampleFreq'  ) THEN GetWord(DesiredHz);
  296.     IF NOT NotInStr(Line, 'TicksPerSec' ) THEN GetWord(TicksPerSecond);
  297.     IF NOT NotInStr(Line, 'ShellFreq'   ) THEN GetWord(ShellHz);
  298.     IF NOT NotInStr(Line, 'MaxFreq'     ) THEN GetWord(MaxOutputFreq);
  299.     IF NOT NotInStr(Line, 'Volume'      ) THEN GetByte(VtVolume);
  300.     IF NOT NotInStr(Line, 'Device'      ) THEN GetString(DevID, SIZEOF(DevID) - 1);
  301.     IF NOT NotInStr(Line, 'FilterOn'    ) THEN GetByte(BYTE(FilterOn));
  302.     IF NOT NotInStr(Line, 'FilterOff'   ) THEN GetByte(BYTE(FilterOff));
  303.     IF NOT NotInStr(Line, 'FilterIsOn'  ) THEN GetBool(FilterIsOn);
  304.     IF NOT NotInStr(Line, 'CanFallBack' ) THEN GetBool(CanFallBack);
  305.     IF NOT NotInStr(Line, 'FilterChange') THEN GetBool(PermitFilterChange);
  306.     IF NOT NotInStr(Line, 'BassFilter'  ) THEN GetBool(DoEqualice);
  307.     IF NOT NotInStr(Line, 'DMAOffset'   ) THEN GetWord(DMAOffset);
  308.     IF NOT NotInStr(Line, 'LowQuality'  ) THEN GetBool(LowQuality);
  309.     IF NOT NotInStr(Line, 'Volume'      ) THEN GetByte(VtVolume);
  310.   END;
  311.  
  312.  
  313. { DoSectDAC. [VT-Misc] section. }
  314.  
  315. PROCEDURE DoSectMisc; FAR;
  316.   BEGIN
  317.     IF NOT NotInStr(Line, 'ShellPath'  ) THEN GetPath  (ShellPath);
  318.     IF NOT NotInStr(Line, 'ShellParams') THEN GetString(ShellParam,   SIZEOF(ShellParam)   - 1);
  319.     IF NOT NotInStr(Line, 'Language')    THEN GetPath  (StringsFName);
  320.     IF NOT NotInStr(Line, 'ModPath')     THEN GetPath  (ModPath);
  321.     IF NOT NotInStr(Line, 'TmpPath')     THEN GetPath  (SwapPrimPath);
  322.   END;
  323.  
  324.  
  325. { DoSectDAC. [VT-Screen] section. }
  326.  
  327. PROCEDURE DoSectScreen; FAR;
  328.   BEGIN
  329.     IF NOT NotInStr(Line, 'ForceEGA') THEN GetBool(ForceEGA);
  330.   END;
  331.  
  332.  
  333. { DoSectGeneric. Generic section interpreter. It calls one of the above. }
  334.  
  335. PROCEDURE DoSectGeneric(Offs: WORD); FAR;
  336.   VAR
  337.     DoSect : POINTER;
  338.   BEGIN
  339.     DoSect := Ptr(SEG(DoSectGeneric), Offs);
  340.     WHILE NOT EoF(ConfFile) DO
  341.       BEGIN
  342.         ReadLn(ConfFile, Line);
  343.         KillSpaces(Line);
  344.         IF (Length(Line) > 0) THEN
  345.           BEGIN
  346.             IF (Line[1] = '[') THEN EXIT;
  347.             IF (Line[1] <> ';') AND
  348.                (Line[1] <> ':') AND
  349.                (Line[1] <> '#') THEN
  350.               ASM
  351.  
  352.                         CALL    [DoSect];
  353.               END;
  354.           END;
  355.       END;
  356.   END;
  357.  
  358.  
  359. { Sections definitions. }
  360.  
  361. TYPE
  362.   SectProc = PROCEDURE;
  363.  
  364. CONST
  365.   NumSects = 6;                                 { Number of controlled sections. }
  366.   SectList : ARRAY[1..NumSects] OF RECORD       { List of controlled sections.   }
  367.                                     Proc : WORD;
  368.                                     Name : STRING[16];
  369.                                   END =  
  370.     ( ( Proc:OFS(DoSectSB);      Name:'[VT-SBlaster]' ) ,
  371.       ( Proc:OFS(DoSectSBPro);   Name:'[VT-SBPro]'    ) ,
  372.       ( Proc:OFS(DoSectPlayMod); Name:'[VT-PlayMod]'  ) ,
  373.       ( Proc:OFS(DoSectDAC);     Name:'[VT-DAC]'      ) ,
  374.       ( Proc:OFS(DoSectMisc);    Name:'[VT-Misc]'     ) ,
  375.       ( Proc:OFS(DoSectScreen);  Name:'[VT-Screen]'   )
  376.     );
  377.  
  378.  
  379.  
  380.  
  381. {----------------------------------------------------------------------------}
  382. { Configuration reader's main loop.                                          }
  383. {____________________________________________________________________________}
  384.  
  385.  
  386. { FindNextSect. Skips until the beginning of the next section. }
  387.  
  388. PROCEDURE FindNextSect;
  389.   BEGIN
  390.     WHILE NOT EoF(ConfFile) DO
  391.       BEGIN
  392.         ReadLn(ConfFile, Line);
  393.         KillSpaces(Line);
  394.         IF (Length(Line) > 0) AND (Line[1] = '[') THEN EXIT;
  395.       END;
  396.   END;
  397.  
  398.  
  399. { ReadConfiguration. Configuration reader. Main loop. }
  400.  
  401. PROCEDURE ReadConfiguration(FName: PathStr);
  402.   VAR
  403.     i    : WORD;
  404.     Good : BOOLEAN;
  405.   BEGIN
  406.     Assign(ConfFIle, FName);
  407.     i := FileMode;
  408.     FileMode := 0;
  409.     Reset(ConfFile);
  410.     FileMode := i;
  411.     IF IOResult <> 0 THEN EXIT;
  412.  
  413.     WHILE NOT EoF(ConfFile) DO
  414.       BEGIN
  415.         FindNextSect;
  416.         Good := TRUE;
  417.         WHILE (Good)              AND
  418.               (NOT EoF(ConfFile)) AND
  419.               (Length(Line) <> 0) AND
  420.               (Line[1] = '[')     DO
  421.           BEGIN
  422.             Good := FALSE;
  423.             FOR i := 1 TO NumSects DO
  424.               IF NOT NotInStr(SectList[i].Name, Line) THEN
  425.                 BEGIN
  426.                   DoSectGeneric(SectList[i].Proc);
  427.                   Good := TRUE;
  428.                 END;
  429.           END;
  430.       END;
  431.  
  432.     Close(ConfFile);
  433.   END;
  434.  
  435.  
  436.  
  437.  
  438. {----------------------------------------------------------------------------}
  439. { Unit initialization code. It reads two configuration files:                }
  440. {   1st. - A file named like the executable, but with the extension .CFG, in }
  441. {          the same directory as the executable.                             }
  442. {   2nd. - A file named VT.CFG in the current directory.                     }
  443. {                                                                            }
  444. { The changes read from the second file may overwrite those read from the    }
  445. { first.                                                                     }
  446. {____________________________________________________________________________}
  447.  
  448. VAR
  449.   Path : PathStr;
  450.   Name : NameStr;
  451.   Ext  : ExtStr;
  452.  
  453. BEGIN
  454.  
  455.   Path := ParamStr(0);          { Executable's full pathname. }
  456.   FSplit(Path, VTDir, Name, Ext);
  457.   IF Name <> 'VT' THEN
  458.     BEGIN
  459.       ReadConfiguration(VTDir+'VT.CFG');
  460.       ReadConfiguration('VT.CFG');
  461.     END;
  462.  
  463.   ReadConfiguration(VTDir+Name+'.CFG');
  464.   ReadConfiguration(Name+'.CFG');
  465.  
  466. END.
  467.